home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
gnu
/
vh-1_5.lha
/
vh-1.5
/
screen.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-11
|
25KB
|
1,195 lines
/*****************************************************************************
NAME
screen.c -- augmented pseudo-curses(3) screen support
SYNOPSIS
int LINES, COLS; -- terminal depth & width globals
int initscr() -- init screen, set LINES and COLS
int endwin() -- de-initialize screen code
int clear() -- clear screen
int refresh() -- refresh real screen from virtual screen
int ungetch(c) -- put c on queue to be grabbed by next getch()
int inch() -- get char from current update location.
int move(y, x) -- move update cursor to row y colum x
int addch(c) -- add char c at update location
int addstr(s) -- write string from update location
int attrset(a) -- set attribute (A_NORMAL, A_REVERSE, A_BOLD)
bool has_color() -- do we have color?
int napms() -- nap for some number of milliseconds
void beep(); -- beep the terminal bell
int egetch() -- get mouse event or character, no echo
void readscr(lx,ly,rx,ry, s) -- get content of screen line
bool has_mouse() -- is there a mouse?
void mouse_init() -- initialize mouse
int mouse_status(py,px) -- get mouse location and button state
void mouse_show() -- show mouse cursor
void mouse_hide() -- hide mouse cursor
DESCRIPTION
The idea here is to present a system-independent interface that looks like
a subset of curses(3), with a minimum of hooks for mouse handling and one
concession to Borland C for optimizations's sake.
The addch() and addstr() functions move the update cursor to the right after
writing. The argument of addch() may have an attribute logical-or'ed in.
The inch() call returns a char with attribute or'ed in; A_CHARTEXT masks out
the character only. The following special keycap defines are used:
KEY_HELP -- not on PC keyboard
KEY_REFRESH -- not on PC keyboard
KEY_NPAGE -- PgDn
KEY_PPAGE -- PgUp
KEY_UP -- Up Arrow
KEY_DOWN -- Down Arrow
KEY_REFERENCE -- not on PC keyboard
KEY_ENTER -- Enter
KEY_RIGHT -- Right Arrow
KEY_LEFT -- Left Arrow
KEY_FIND -- not on PC keyboard
KEY_SFIND -- not on PC keyboard
KEY_SELECT -- not on PC keyboard
KEY_HOME -- Home
KEY_BEG -- not on PC keyboard
KEY_END -- End
KEY_UNDO -- not on PC keyboard
KEY_PRINT -- not on PC keyboard
KEY_MOUSE -- mouse event happened (not supported by curses(3))
Mouse state defines returned by mouse_status():
LEFT_DOWN -- left mouse button down
LEFT_UP -- left mouse button release
RIGHT_DOWN -- right mouse button down
RIGHT_UP -- right mouse button up
Special mouse coordinate values:
CMDLINE -- command line of application window
THUMBCOL -- thumb column of application window
BUGS
The MS-DOS implementation doesn't do optimization for the
scrolling case.
AUTHORS
Package interface design and UNIX curses(3) code by Eric S. Raymond.
MS-DOS code by Raymond D. Gardner.
Please see the READ.ME in this directory for license terms.
******************************************************************************/
/* LINTLIBRARY */
#include <assert.h>
#include "screen.h"
#ifdef CURSES
/*******************************************************************
*
* Support for curses(3) under UNIX.
*
******************************************************************/
#ifdef MOUSE
#include <fcntl.h>
#include <sys/mouse.h>
/*
* We want to make the mouse relatively insensitive to small motions.
* The code ignores all but 1 in MXSCALE horizontal motions and 1 in MYSCALE
* vertical motions. The factors differ as they do because most fonts have
* a roghly 2/1 aspect ratio; thus, to get the same real rate of vertical
* motion as horizontal, MYSCALE should be twice as large.
*/
#define MXSCALE 2
#define MYSCALE (MXSCALE * 2)
static int mousefd; /* mouse file descriptir */
static int msy, msx; /* current mouse coordinates */
static int mstat; /* current mouse status */
static bool mvis = TRUE; /* should cursor be visible? */
static bool mcolor; /* show mouse cursor in color? */
#endif /* MOUSE */
void mouse_init()
/* initialize the mouse */
{
#ifdef MOUSE
/*
* If there's an active mouse, set O_NODELAY on input so we
* can alternate polling for keystrokes and mouse events without
* blocking.
*/
if ((mousefd = open("/dev/mouse", O_RDONLY)) != ERR)
nodelay(stdscr, TRUE);
#endif /* MOUSE */
#ifdef SCROLLBAR
COLS--;
#endif /* SCROLLBAR */
}
void mouse_color(on)
/* should the mouse cursor be in color? */
bool on;
{
#ifdef MOUSE
if (on && has_colors())
init_pair(COLOR_PAIRS - 1, COLOR_BLACK, COLOR_YELLOW);
mcolor = on;
#endif /* MOUSE */
}
void mouse_move(y, x)
/* move the mouse hotspot to a given location */
int y, x;
{
#ifdef MOUSE
msy = y;
msx = x;
#endif /* MOUSE */
}
void mouse_show()
{
#ifdef MOUSE
mvis = TRUE;
#endif /* MOUSE */
}
void mouse_hide()
{
#ifdef MOUSE
mvis = FALSE;
#endif /* MOUSE */
}
int mouse_status(py, px)
/* get current mouse status, return coordinates */
int *py, *px;
{
#ifdef MOUSE
if (mousefd != ERR)
{
#ifdef SCROLLBAR
*px = (msx == COLS) ? THUMBCOL : msx;
#else
*px = msx;
#endif /* SCROLLBAR */
*py = msy;
return(mstat);
}
#endif /* MOUSE */
return(*px = *py = ERR);
}
static int cgetch()
/* get single character or mouse event */
{
#ifndef MOUSE
return(getch());
#else
#ifdef ATTMOUSE
struct mouseinfo m;
#endif /* ATTMOUSE */
int mchattr, oldx, oldy, oldmy, oldmx;
int c;
if (mousefd == ERR)
return(getch());
if (mvis)
{
getyx(stdscr, oldy, oldx);
move(msy, msx);
mchattr = inch();
move(msy, msx);
if (mcolor)
addch((mchattr & 0xff) | COLOR_PAIR(COLOR_PAIRS - 1));
else
addch(mchattr ^ A_REVERSE);
oldmy = msy; oldmx = msx;
refresh();
}
for (;;)
{
/* first poll for a character */
if ((c = getch()) != ERR)
break;
/* then poll for a mouse event */
#ifdef ATTMOUSE
(void) ioctl(mousefd, MOUSEIOCREAD, &m);
if ((m.status &~ MOVEMENT) | m.xmotion | m.ymotion)
{
register i, newx, newy;
newx = msx;
if (m.xmotion < 0)
for (i = 0; i < -(m.xmotion / MXSCALE); i++)
if (newx <= 0)
break;
else
newx--;
if (m.xmotion > 0)
for (i = 0; i < (m.xmotion / MXSCALE); i++)
#ifdef SCROLLBAR
if (newx >= COLS)
#else
if (newx >= COLS - 1)
#endif /* SCROLLBAR */
break;
else
newx++;
msx = newx;
newy = msy;
if (m.ymotion < 0)
for (i = 0; i < -(m.ymotion / MYSCALE); i++)
if (newy <= 0)
break;
else
newy--;
if (m.ymotion > 0)
for (i = 0; i < (m.ymotion / MYSCALE); i++)
if (newy >= LINES - 1)
break;
else
newy++;
msy = newy;
mstat = 0;
if (m.status & BUT1CHNG)
if (m.status & BUT1STAT)
mstat |= BUTTON1_PRESSED;
else
mstat |= BUTTON1_RELEASED;
if (m.status & BUT3CHNG)
if (m.status & BUT3STAT)
mstat |= BUTTON3_PRESSED;
else
mstat |= BUTTON3_RELEASED;
c = KEY_MOUSE;
break;
}
/* keep polling till you get one or the other */
}
#endif /* ATTMOUSE */
if (mvis)
{
move(oldmy, oldmx);
addch(mchattr);
move(oldy, oldx);
}
return(c);
#endif /* MOUSE */
}
void readscr(lx, ly, rx, ry, outbuf)
/* get text from screen */
int lx, ly, rx, ry;
char *outbuf;
{
int x, y;
for (x = lx; x <= rx; x++)
for (y = ly; y <= ry; y++)
{
move(y, x);
*outbuf++ = inch() & A_CHARTEXT;
}
*outbuf = '\0';
}
#ifndef A_COLOR
bool has_colors()
{
return(FALSE);
}
int start_color()
{
/* do nothing */
}
int init_pair(pn, fg, bg)
int pn, fg, bg;
{
/* do nothing */
}
#endif /* A_COLOR */
#endif /* CURSES */
#ifdef BSD
/*******************************************************************
*
* Support for BSD, which is missing some stuff...
*
******************************************************************/
int attrset(a)
/* set write attribute for subsequent operations */
chtype a;
{
/*
* It would be real nice to have more attributes supported in here...
*/
if (a | A_REVERSE)
standout();
else
standend();
return(OK);
}
void beep()
{
(void) putchar('\007');
}
int start_color()
{
/* do nothing */
}
/*ARGSUSED0*/
int init_pair(pn, fg, bg)
int pn, fg, bg;
{
/* do nothing */
}
unsigned char acs_map[] =
{
/* ACS_BSSB */ '+',
/* ACS_SSBB */ '+',
/* ACS_BBSS */ '+',
/* ACS_SBBS */ '+',
/* ACS_SBSS */ '|',
/* ACS_SSSB */ '|',
/* ACS_SSBS */ '-',
/* ACS_BSSS */ '-',
/* ACS_BSBS */ '-',
/* ACS_SBSB */ '|',
/* ACS_SSSS */ '+',
/* ACS_S1 */ '~', /* scan line 1 */
/* ACS_S9 */ '_', /* scan line 9 */
/* ACS_DIAMOND */ '*', /* diamond */
/* ACS_CKBOARD */ '#', /* checker board */
/* ACS_DEGREE */ 'o', /* degree symbol */
/* ACS_PLMINUS */ '#', /* plus/minus */
/* ACS_BULLET */ '*', /* bullet */
/* ACS_LARROW */ 27, /* arrow pointing left */
/* ACS_RARROW */ '>', /* arrow pointing right */
/* ACS_DARROW */ 'V', /* arrow pointing down */
/* ACS_UARROW */ '^', /* arrow pointing up */
/* ACS_BOARD */ '#', /* board of squares */
/* ACS_LANTERN */ '#', /* lantern symbol */
/* ACS_BLOCK */ '#', /* solid square block */
};
#endif /* BSD */
#ifdef MSDOS
/*******************************************************************
*
* Support for Borland C under MS-DOS
*
******************************************************************/
#include <dos.h>
#include <conio.h>
#define GQDEPTH 32 /* depth of character push queue */
int LINES, COLS, COLOR_PAIRS, COLORS = 8;
/* vtype values */
#define PGA (7)
#define VGA (6)
#define MCGA (5)
#define EGA (4)
#define CGA (3)
#define HERC (2)
#define MDA (1)
#define NONE (0)
#define VUNKNOWN (-1)
/* hascolor values: */
#define COLOR (2)
#define MONO (1)
static int hascolor;
static char screensave[MAXROWS*MAXCOLS*2]; /* save user's screen here */
int bufseg; /* vid buffer segment addr for emulating gettext/puttext */
#ifdef __TURBOC__
bool has_snowy_CGA = FALSE;
#endif /* __TURBOC__ */
int initscr()
{
union REGS r;
struct SREGS s;
int vtype, vchrome, xmode, *mode = &xmode;
/* default assumptions */
hascolor = 0;
LINES = 25;
bufseg = 0xb800;
/* get mode and columns */
r.h.ah = 0x0F;
int86(0x10, &r, &r);
*mode = r.h.al;
COLS = r.h.ah;
r.x.ax = 0x1200; /* alternate function select */
r.x.bx = 0x0010;
int86(0x10, &r, &r);
if (r.x.bx != 0x0010) /* must be pga/vga/mcga/ps2/ega */
{
vtype = EGA; /* provisional assumption */
hascolor = r.h.bh ? MONO : COLOR;
/* now try for "higher" display than EGA */
r.x.ax = 0x1A00; /* get display combination */
int86(0x10, &r, &r);
if (r.h.al == 0x1A) /* must be pga/vga/mcga/ps2 */
{
switch (r.h.bl)
{
case 0: vtype = NONE; break;
case 1: vtype = MDA; break;
case 2: vtype = CGA; break;
case 4: vtype = EGA; break;
case 5: vtype = EGA; break;
case 6: vtype = PGA; break;
case 7: vtype = VGA; break;
case 8: vtype = VGA; break;
case 0xC: /* fall through; analog vs. digital display */
case 0xA: vtype = MCGA; break;
case 0xB: vtype = MCGA; break;
default:
vtype = VUNKNOWN;
break;
}
}
/* get number of rows on screen */
if (vtype == EGA || vtype == MCGA || vtype == VGA)
{
segread(&s);
r.x.ax = 0x1130; /* get font info */
r.h.bh = 0;
int86x(0x10, &r, &r, &s);
LINES = r.h.dl + 1;
}
else
LINES = *(int far *)MK_FP(0x40, 0x84);
}
else
{ /* not pga/vga/mcga/ps2/ega */
if (*mode != 7)
vtype = CGA;
else
{
vtype = MDA;
hascolor = MONO;
}
}
bufseg = 0xb800;
if (vtype == MDA || hascolor == MONO)
bufseg = 0xb000;
gettext(1, 1, COLS, LINES, screensave); /* save user's screen */
#ifdef SCROLLBAR
COLS--;
#endif /* SCROLLBAR */
#ifdef __TURBOC__
{
extern int _video[12];
if (! has_snowy_CGA)
_video[5] = 0;
}
#endif
return OK;
}
#ifdef __ZTC__
/*******************************************************************
*
* gettext()/puttext() -- simulate Borland screen i/o routines
*
*******************************************************************/
int puttext(int left, int top, int right, int bot, char *buf)
{
int cols, row;
char far *vid;
char far *vidstart;
char *lim;
cols = right - left + 1;
--left;
--top;
vidstart = vid = MK_FP(bufseg, top*160+left*2);
for ( row = top; row < bot; ++ row )
{
for ( lim = buf + cols * 2; buf < lim; )
*vid++ = *buf++;
vid = vidstart += 160;
}
return 0;
}
int gettext(int left, int top, int right, int bot, char *buf)
{
int cols, row;
char far *vid;
char far *vidstart;
char *lim;
cols = right - left + 1;
--left;
--top;
vidstart = vid = MK_FP(bufseg, top*160+left*2);
for ( row = top; row < bot; ++ row )
{
for ( lim = buf + cols * 2; buf < lim; )
*buf++ = *vid++;
vid = vidstart += 160;
}
return 0;
}
#endif /* __ZTC__ */
int endwin()
/* de-initialize window handling */
{
#ifdef SCROLLBAR
COLS++;
#endif /* SCROLLBAR */
puttext(1, 1, COLS, LINES, screensave); /* restore user screen */
move(LINES-1,0);
return OK;
}
bool has_colors()
/* is color available? */
{
return(hascolor == COLOR);
}
void readscr(int left, int top, int right, int bot, char *buf0)
/* read the text out of screen region into a buffer */
{
char s[MAXCOLS * 2];
register char *buf;
register char *p;
register int k;
int size;
buf = buf0;
k = (bot-top+1)*(right-left+1);
assert(k <= MAXCOLS);
gettext(left+1, top+1, right+1, bot+1, s);
p = s;
do
{
*buf++ = *p;
p += 2;
} while ( --k );
*buf = 0;
}
int refresh()
{
/* do nothing; this is a write-through implementation */
return OK;
}
/********************** mouse routines ************************/
static bool mse = FALSE; /* nonzero iff mouse is present */
bool has_mouse()
/* is there a mouse? */
{
return(mse);
}
void mouse_color(on)
/* show mouse cursor in color? */
bool on;
{
(void)on; /* quiet the compiler warning */
/* do nothing */
}
void mouse_init()
/* initialize the mouse */
{
union REGS r;
struct SREGS sregs;
segread(&sregs);
r.x.ax = 0x3533;
int86x(0x21, &r, &r, &sregs); /* get mouse driver int addr */
if (sregs.es == 0 && r.x.bx == 0) /* if addr is zero, no mouse */
return;
/* if addr points to IRET, no mouse */
if (*(unsigned char far *)MK_FP(sregs.es, r.x.bx) == 0xcf)
return;
r.x.ax = 0;
int86(0x33, &r, &r); /* try to init mouse driver */
mse = r.x.ax; /* set mouse status global var */
mouse_show();
}
void mouse_show()
/* turn on the mouse cursor */
{
union REGS r;
if (mse)
{
r.x.ax = 1;
int86(0x33, &r, &r);
}
}
void mouse_hide()
/* turn off mouse cursor */
{
union REGS r;
if (mse)
{
r.x.ax = 2;
int86(0x33, &r, &r);
}
}
void mouse_move(y, x)
/* set mouse cursor position (zero-origin coordinates) */
int y, x;
{
union REGS r;
if (mse)
{
r.x.ax = 4;
r.x.cx = x << 3;
r.x.dx = y << 3;
int86(0x33, &r, &r);
}
}
/******************* screen/cursor routines ****************/
static int cury, curx; /* virtual update cursor */
static chtype cattr; /* current attribute */
static chtype pairs[64]; /* color pair array */
int move(row, col)
/* cursor positioning */
int row, col;
{
union REGS regs;
mouse_hide();
regs.h.ah = 2;
regs.h.bh = 0;
regs.h.dh = row;
regs.h.dl = col;
int86(0x10, ®s, ®s);
mouse_show();
cury = row;
curx = col;
return 0;
}
int getyx(row, col)
/* get current cursor position */
int *row;
int *col;
{
*row = cury;
*col = curx;
return 0;
}
static void scroll(forward, nlines, attr, top, bot, left, right)
/* scroll screen region */
bool forward;
int nlines, attr, top, bot, left, right;
{
union REGS regs;
mouse_hide();
regs.h.ah = 6 + !forward;
regs.h.al = nlines;
regs.h.bh = attr;
regs.h.ch = top;
regs.h.cl = left;
regs.h.dh = bot;
regs.h.dl = right;
int86(0x10, ®s, ®s);
mouse_show();
}
int clear()
{
scroll(TRUE, 0, pcattr(cattr), 0, LINES - 1, 0, COLS - 1);
move(0, 0);
return OK;
}
int pcattr(a)
/* map A_* and color attributes to the bits in IBM CGA/EGA attribute words */
chtype a;
{
chtype attr = 0;
int p;
#ifdef RDGOPT
static chtype prevarg = -1234; /* very unlikely first value */
static int prevattr;
if ( a == prevarg ) /* if same arg as last one ... */
return prevattr; /* ... return prev value */
prevarg = a; /* save for next time */
#endif /* RDGOPT */
if ( ! (a & A_COLOR) )
{
/* monochrome attributes */
attr = 0x0007; /* "normal" attr */
if (a & A_STANDOUT) attr = 0x0070;
if (a & A_REVERSE) attr = 0x0070;
if (a & A_BLINK) attr |= 0x0080;
if (a & A_UNDERLINE) attr |= 0x0001;
}
else
{
/* color setup */
if (p = PAIR_NUMBER(a))
attr |= pairs[p];
}
if (a & A_BOLD) attr |= 0x0008; /* works for color or mono */
#ifdef RDGOPT
prevattr = attr; /* save for next time */
#endif /* RDGOPT */
return(attr);
}
static void swrite(row, col, s0, attr)
/* write data, starting at given row/col, with given attribute */
int row, col;
char *s0;
int attr;
{
char buf[MAXCOLS * 2];
register char *s;
++row;
++col;
s = s0;
if ( *s )
{
register int *p;
register int n;
n = strlen(s);
p = (int *)buf;
memset(buf, attr, n * 2);
*(char *)p = *s;
--n;
if ( n )
{
do
{
*(char *)(++p) = *++s;
} while ( --n );
}
++s;
}
mouse_hide();
if ( s > s0 )
puttext(col, row, col + (s - s0) - 1, row, buf);
mouse_show();
}
int attrset(a)
/* set write attribute for subsequent operations */
chtype a;
{
cattr = a;
return(OK);
}
int start_color()
{
if (!has_colors())
return(ERR);
COLOR_PAIRS = sizeof(pairs) / sizeof(int);
return(OK);
}
int init_pair(n, fg, bg)
/* initialize a given color pair to given foreground/background combination */
int n, fg, bg;
{
/*
* By a not-so-amazing coincidence, the numbers of the 8 basic
* curses(3) colors are precisely the RGB bit patters needed
* to coerce an IBM CGA adapter.
*/
if (n < COLOR_PAIRS)
{
pairs[n] = (bg << 4) | fg;
return(OK);
}
else
return(ERR);
}
int addstr(s)
/* write a string to the screen, advancing the update cursor */
char *s;
{
swrite(cury, curx, s, pcattr(cattr));
curx += strlen(s);
return(OK);
}
int _addch(c)
/* write a character to the screen, advancing the update cursor */
chtype c;
{
static char s[2];
chtype attr;
if ( (attr = c & A_ATTRIBUTES) == 0 )
attr = cattr;
s[0] = c;
swrite(cury, curx, s, pcattr(attr));
curx++;
return(OK);
}
/*********** keyboard & mouse handling *****************/
/* status variables for last mouse event */
static int lastx, lasty; /* last mouse position */
static int lastevent; /* last button event */
/* We use MSDOS function 6 (direct console i/o) to avoid problems
** with control-c/control-break checking
*/
static int dos06(int ch) /* ch is -1 for input; anything else for output */
{
#define ZFLAG 0x40
union REGS r;
r.h.ah = 6;
r.h.dl = ch;
intdos(&r, &r);
if ( ch == -1 )
return r.x.flags & ZFLAG ? -1 : r.h.al;
else
return 0;
}
static int cinp(int nowait)
{
int r;
do
{
r = dos06(-1);
} while ( ! nowait && r == -1 );
if ( r == 0 )
{
r = 256 + dos06(-1);
assert(r > 256);
}
else if ( r == -1 )
{
r = 0;
}
return r;
}
static int getkey()
{
return cinp(FALSE);
}
static int getkeynowait()
{
return cinp(TRUE);
}
int mse_status_raw(py, px)
int *px, *py;
{
union REGS r;
r.x.ax = 3;
int86(0x33, &r, &r);
*px = r.x.cx >> 3; /* translate coords to col/row */
*py = r.x.dx >> 3;
return r.x.bx;
}
static int cgetch()
/* return next keypress or mouse click */
{
static int left_was_down = FALSE;
static int right_was_down = FALSE;
int code;
/* no mouse? then just get a keystroke */
if (!mse)
code = getkey();
else /* there's a mouse; wait on event */
for (;;)
{
int x, y, mse_stat;
if (code = getkeynowait())
break;
#if 00
mse_stat = mouse_status(&y, &x);
#endif
/* poll the mouse */
mse_stat = mse_status_raw(&lasty, &lastx);
if ( mse_stat & 1 )
{
if ( ! left_was_down )
{
left_was_down = TRUE;
lastevent = (lastevent & ~ BUTTON1_RELEASED) | BUTTON1_PRESSED;
return KEY_MOUSE;
}
else
{
#ifdef SCROLLBAR
napms(150);
if ( mse_status_raw(&lasty, &lastx) & 1 && lastx == COLS )
{
lastevent =
(lastevent & ~ BUTTON1_RELEASED) | BUTTON1_PRESSED;
return KEY_MOUSE;
}
#endif /* SCROLLBAR */
}
}
else
{
if ( left_was_down )
{
left_was_down = FALSE;
lastevent = (lastevent & ~ BUTTON1_PRESSED) | BUTTON1_RELEASED;
return KEY_MOUSE;
}
else
lastevent = 0;
}
if ( mse_stat & 2 )
{
if ( ! right_was_down )
{
right_was_down = TRUE;
lastevent = (lastevent & ~ BUTTON3_RELEASED) | BUTTON3_PRESSED;
return KEY_MOUSE;
}
}
else
{
if ( right_was_down )
{
right_was_down = FALSE;
lastevent = (lastevent & ~ BUTTON3_PRESSED) | BUTTON3_RELEASED;
return KEY_MOUSE;
}
else
lastevent = 0;
}
#if 00
lastevent = 0;
if ((mse_stat & 0x01) != left_was_down)
{
lastevent |= (left_was_down ? BUTTON1_RELEASED : BUTTON1_PRESSED);
left_was_down = !left_was_down;
return(KEY_MOUSE);
}
if ((mse_stat & 0x02) != right_was_down)
{
lastevent |= (right_was_down ? BUTTON3_RELEASED : BUTTON3_PRESSED);
right_was_down = !right_was_down;
return(KEY_MOUSE);
}
#endif
}
/* special-key code translation */
switch (code)
{
case 315: return(KEY_F(1)); /* break; */
case 316: return(KEY_F(2)); /* break; */
case 317: return(KEY_F(3)); /* break; */
case 318: return(KEY_F(4)); /* break; */
case 319: return(KEY_F(5)); /* break; */
case 320: return(KEY_F(6)); /* break; */
case 321: return(KEY_F(7)); /* break; */
case 322: return(KEY_F(8)); /* break; */
case 323: return(KEY_F(9)); /* break; */
case 324: return(KEY_F(10)); /* break; */
case 328: return(KEY_UP); /* break; */
case 336: return(KEY_DOWN); /* break; */
case 331: return(KEY_LEFT); /* break; */
case 333: return(KEY_RIGHT); /* break; */
case 335: return(KEY_END); /* break; */
case 327: return(KEY_HOME); /* break; */
case 337: return(KEY_NPAGE); /* break; */
case 329: return(KEY_PPAGE); /* break; */
default: break;
}
return(code);
}
int mouse_status(py, px)
/* return status caught by last mouse button event */
int *py, *px;
{
*py = lasty;
#ifdef SCROLLBAR
*px = (lastx == COLS) ? THUMBCOL : lastx;
#else
*px = lastx;
#endif /* SCROLLBAR */
return(lastevent);
}
int inch()
/* get character and attribute at current update position */
{
char buf[4];
gettext(curx + 1, cury + 1, curx + 1, cury + 1, buf);
return(buf[0]);
}
#include <time.h>
#define millisecs() ((clock() * 10000)/(int)(double)(0.5+CLK_TCK*10))
int napms(n)
/* sleep for n milliseconds */
int n;
{
long t0 = millisecs() + n;
while (millisecs() < t0)
continue;
return(millisecs());
}
void beep()
{
(void) putchar('\007');
}
unsigned char acs_map[] =
{
/* ACS_BSSB */ 218,
/* ACS_SSBB */ 192,
/* ACS_BBSS */ 191,
/* ACS_SBBS */ 217,
/* ACS_SBSS */ 180,
/* ACS_SSSB */ 195,
/* ACS_SSBS */ 193,
/* ACS_BSSS */ 194,
/* ACS_BSBS */ 196,
/* ACS_SBSB */ 179,
/* ACS_SSSS */ 197,
/* ACS_S1 */ 223, /* scan line 1 (actually top-half on) */
/* ACS_S9 */ 22, /* scan line 9 */
/* ACS_DIAMOND */ 254, /* diamond (actually bullet) */
/* ACS_CKBOARD */ 178, /* checker board (stipple) */
/* ACS_DEGREE */ 248, /* degree symbol */
/* ACS_PLMINUS */ 241, /* plus/minus */
/* ACS_BULLET */ 254, /* bullet */
/* ACS_LARROW */ 27, /* arrow pointing left */
/* ACS_RARROW */ 26, /* arrow pointing right */
/* ACS_DARROW */ 25, /* arrow pointing down */
/* ACS_UARROW */ 24, /* arrow pointing up */
/* ACS_BOARD */ 220, /* board of squares */
/* ACS_LANTERN */ 15, /* lantern symbol */
/* ACS_BLOCK */ 219, /* solid square block */
};
#endif /* MSDOS */
#if !defined(CURSES) || defined(BSD) || defined(AMIGA)
/* character push queue */
static chtype getchq[GQDEPTH];
static int gqc = 0;
int egetch()
/* get single character or mouse event */
{
/* queued characters waiting? then go */
if (gqc > 0)
return(getchq[--gqc]);
else
return(cgetch());
}
int ungetch(c)
/* try to queue a character for input */
int c;
{
if (gqc >= GQDEPTH)
return(ERR);
else
{
getchq[gqc++] = c;
return(OK);
}
}
#else
int egetch()
/* get single character or mouse event */
{
return(cgetch());
}
#endif /* !defined(CURSES) || defined(BSD) */
/* screen.c ends here */